﻿using DataWorks_Sqlite.MappingClass;
using DataWorks_Tools.BasicMethods;
using DataWorks_Tools.HalfHourCalSave.BinImort;
using DataWorks_Tools.HalfHourCalSave.Common.DataImport;
using DataWorks_Tools.MappModals;
using DataWorks_Tools.MappModals.CalInputModals;
using DataWorks_Tools.MappModals.CalSaveModals;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using static DataWorks_Tools.HalfHourCalSave.Common.Basic.EnumClass;

namespace DataWorks_Tools.HalfHourCalSave
{
    public static class HalfHourCalSaveMethods
    {
        static string[] filenames = new string[]
        {
            "dia_import_spd.csv",
            "dia_import_rpm.csv",
            "dia_import_gps.csv",
            "dia_import_statistic.csv",
            "dia_import_steering.csv",
            "dia_import_spdfromto.csv",
            "dia_import_rpcount.csv",
            "dia_import_record.csv"
        };
        [Obsolete]
        public static async Task<List<string>> YXHExcuteHalfHourSaveAsync(HalfHourCalInputModel row, dw_props_admin admin)
        {
            List<string> result = new List<string>
            {
                "开始进行半小时计算"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
            };//专用于输出程序计算过程中的错误信息
            //获得用户输入的日期和路径下的日期文件夹名称相同的文件夹
            var sd = Convert.ToDateTime(row.startdate);
            var ed = Convert.ToDateTime(row.enddate);
            if (sd.Year != ed.Year)
            {
                var noinfo = $"注意：不能跨年！！！ {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}{Environment.NewLine}";
                result.Add(noinfo);
                return result;
            }
            var directories = DateTimeMethods.YXHGetDirectoryArrayfromDate(row);
            Stopwatch Stimer = new Stopwatch();
            Stimer.Start();
            if (directories.Length > 0)
            {
                foreach (var d in directories)
                {
                    var dirname = new DirectoryInfo(d).Name;
                    result.Add($"开始进行{dirname}下的半小时计算  {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
                    Stopwatch dtimer = new Stopwatch();
                    dtimer.Start();
                    var csvfiles = d.YXHGetAllextFiles("*.csv");
                    var csvyear = csvfiles.First().Name.Split('_')[0];
                    var csvdate = csvfiles.First().Name.Split('-')[0];
                    //DateTime date = DateTime.ParseExact(csvdate, "yyyy_MM_dd", CultureInfo.InvariantCulture);
                    //转为int的年份
                    int.TryParse(csvyear, out var year);
                    if (year == sd.Year || year == ed.Year)
                    {
                        if (csvfiles.Length > 0)
                        {
                            calsave_alllist calsave_Alllist=new calsave_alllist();
                            foreach (var csvfile in csvfiles)
                            {
                                if (csvfile.FullName.YXHFileIsZero())
                                {
                                    result.Add($"{dirname}下的{csvfile.Name}文件大小为0kb");
                                    return result;
                                };
                                result.Add($"开始进行{dirname}下的{csvfile.Name}文件半小时计算  {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                                var data = await ReadfromCSV.GetDatafromCSVAsync(csvfile);
                                result.Add($"{dirname}下的{csvfile.Name}文件读取数据完成时间为{dtimer.Elapsed.TotalMinutes:0.00}分   {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                                if (data.status == 0)
                                {
                                    var spddis = await Tools_BinImport.GetHalfHourSpdAsync(data, row, DisorTimeType.Distance);
                                    if (spddis != null)
                                    {
                                        calsave_Alllist.spdlst.Add(spddis);
                                    }
                                    var spdtime = await Tools_BinImport.GetHalfHourSpdAsync(data, row, DisorTimeType.Time);
                                    if (spdtime != null)
                                    {
                                        calsave_Alllist.spdlst.Add(spdtime);
                                    }
                                    var rpmdis = await Tools_BinImport.GetHalfHourEngRpmAsync(data, row, DisorTimeType.Distance);
                                    if (rpmdis != null)
                                    {
                                        calsave_Alllist.rpmlst.Add(rpmdis);
                                    }
                                    var rpmtime = await Tools_BinImport.GetHalfHourEngRpmAsync(data, row, DisorTimeType.Time);
                                    if (rpmtime != null)
                                    {
                                        calsave_Alllist.rpmlst.Add(rpmtime);
                                    }
                                    var gps = await Tools_GPSImport.GetHalfHourGPSAsync(data, row, admin.gpsreductiontimes);
                                    if (gps.Count>0)
                                    {
                                        calsave_Alllist.gpslst.AddRange(gps);
                                    }
                                    var statistic = await Tools_StatisticImport.GetHalfHourStatisticAsync(data, row,admin.binnumber);
                                    if (statistic.Count > 0)
                                    {
                                        calsave_Alllist.statisticlst.AddRange(statistic);
                                    }
                                    var steering = await Tools_SteeringImport.GetSteeringV2Async(data, admin, row);
                                    if (steering.Count>0)
                                    {
                                        calsave_Alllist.steeringlst.AddRange(steering);
                                    }
                                    var spdfromto = await Tools_SpdFromtoImport.GetSpdFromtoAsync(data, admin, row);
                                    if (spdfromto.Count > 0)
                                    {
                                        calsave_Alllist.spdfromtolst.AddRange(spdfromto);
                                    }
                                }
                                else
                                {
                                    var error = data.status == 1 ? "有空值或NaN" : data.status == 2 ? "不是数字" : "文件被占用";
                                    var info = $"{row.vehicle}文件夹{dirname}的{csvfile.Name}的列名为{data.errorname}行号为{data.errorrow}半小时速度出现了错误为{error} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}{Environment.NewLine}";
                                    result.Add(info);
                                    return result;
                                }
                            }
                            //以下是添加记录表的数据
                            if (calsave_Alllist.spdlst.Count > 0)
                            {
                                var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.spd);
                                calsave_Alllist.recordlst.Add(record);
                            }
                            if (calsave_Alllist.rpmlst.Count > 0)
                            {
                                var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.engrpm);
                                calsave_Alllist.recordlst.Add(record);
                            }
                            if (calsave_Alllist.gpslst.Count > 0)
                            {
                                var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.gps);
                                calsave_Alllist.recordlst.Add(record);
                            }
                            if (calsave_Alllist.statisticlst.Count > 0)
                            {
                                var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.statistics);
                                calsave_Alllist.recordlst.Add(record);
                            }
                            if (calsave_Alllist.steeringlst.Count > 0)
                            {
                                var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.steering);
                                calsave_Alllist.recordlst.Add(record);
                            }
                            if (calsave_Alllist.spdfromtolst.Count > 0)
                            {
                                var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.spdfromto);
                                calsave_Alllist.recordlst.Add(record);
                            }
                            //先创建输出文件夹
                            var newsavepath = row.savepath.YXHPathReplace();
                            Directory.CreateDirectory(newsavepath);
                            var newsavedir=Path.Combine(newsavepath, dirname);
                            result.Add($"开始进行{dirname}文件半小时保存  {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                            await YXHCreateCSVAsync(calsave_Alllist, newsavedir);
                            result.Add($"{dirname}文件半小时保存完毕  {DateTime.Now:yyyy-MM-dd HH:mm:ss}");

                            dtimer.Stop();
                            result.Add($"{dirname}半小时计算完成时间为{dtimer.Elapsed.TotalMinutes:0.00}分");
                        }
                    }
                    else
                    {
                        var noinfo = $"你选的年份和csv文件的年份不相等，请重新选择日期 {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}{Environment.NewLine}";
                        result.Add(noinfo);
                        return result;
                    }
                    Stimer.Stop();
                    result.Add($"半小时计算完成总时间为{Stimer.Elapsed.TotalMinutes:0.00}分");
                }
            }
            else
            {
                var noinfo = $"你选的路径{row.inputpath}没有{row.vehicle}的数据 {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}{Environment.NewLine}";
                result.Add(noinfo);
            }
           
            return result;
        }

        public static async Task<List<string>> YXHExcuteHalfHourSaveMultiThreadAsync(HalfHourCalInputModel row, dw_props_admin admin)
        {
            List<string> result = new List<string>
            {
                "开始进行半小时计算"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
            };//专用于输出程序计算过程中的错误信息
              //获得用户输入的日期和路径下的日期文件夹名称相同的文件夹
            var sd = Convert.ToDateTime(row.startdate);
            var ed = Convert.ToDateTime(row.enddate);
            if(sd.Year!=ed.Year)
            {
                var noinfo = $"注意：不能跨年！！！ {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}{Environment.NewLine}";
                result.Add(noinfo);
                return result;
            }
            var directories = DateTimeMethods.YXHGetDirectoryArrayfromDate(row);
            if (directories.Length > 0)
            {
                Stopwatch Stimer = new Stopwatch();
                Stimer.Start();
                List<Task> tasks = new List<Task>();
                foreach (var d in directories)
                {
                    var dirname = new DirectoryInfo(d).Name;
                    result.Add($"开始进行{dirname}下的半小时计算  {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
                    Task task = Task.Run(async () => {
                        Stopwatch dtimer = new Stopwatch();
                        dtimer.Start();
                        var csvfiles = d.YXHGetAllextFiles("*.csv");
                        var csvyear = csvfiles.First().Name.Split('_')[0];
                        var csvdate = csvfiles.First().Name.Split('-')[0];
                        //DateTime date = DateTime.ParseExact(csvdate, "yyyy_MM_dd", CultureInfo.InvariantCulture);
                        //转为int的年份
                        int.TryParse(csvyear, out var year);
                        if (year == sd.Year || year == ed.Year)
                        {
                            
                            if (csvfiles.Length > 0)
                            {
                                calsave_alllist calsave_Alllist = new calsave_alllist();
                                foreach (var csvfile in csvfiles)
                                {
                                    if (csvfile.FullName.YXHFileIsZero())
                                    {
                                        result.Add($"{new DirectoryInfo(d).Name}下的{csvfile.Name}文件大小为0kb");
                                        return ;
                                    };
                                    //result.Add($"开始进行{dirname}下的{csvfile.Name}文件半小时计算  {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                                    var data = await ReadfromCSV.GetDatafromCSVAsync(csvfile);
                                    //result.Add($"读取{dirname}下的{csvfile.Name}文件数据完成时间为{dtimer.Elapsed.TotalMinutes:0.00}分   {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                                    if (data.status == 0)
                                    {
                                        var spddis = await Tools_BinImport.GetHalfHourSpdAsync(data, row, DisorTimeType.Distance);
                                        if (spddis != null)
                                        {
                                            calsave_Alllist.spdlst.Add(spddis);
                                        }
                                        var spdtime = await Tools_BinImport.GetHalfHourSpdAsync(data, row, DisorTimeType.Time);
                                        if (spdtime != null)
                                        {
                                            calsave_Alllist.spdlst.Add(spdtime);
                                        }
                                        var rpmdis = await Tools_BinImport.GetHalfHourEngRpmAsync(data, row, DisorTimeType.Distance);
                                        if (rpmdis != null)
                                        {
                                            calsave_Alllist.rpmlst.Add(rpmdis);
                                        }
                                        var rpmtime = await Tools_BinImport.GetHalfHourEngRpmAsync(data, row, DisorTimeType.Time);
                                        if (rpmtime != null)
                                        {
                                            calsave_Alllist.rpmlst.Add(rpmtime);
                                        }
                                        var gps = await Tools_GPSImport.GetHalfHourGPSAsync(data, row, admin.gpsreductiontimes);
                                        if (gps.Count > 0)
                                        {
                                            calsave_Alllist.gpslst.AddRange(gps);
                                        }
                                        //这里获得的是统计和RP的结果
                                        var starp = await Tools_StatisticImport.GetHalfHourStatisticandRPAsync(data, row,admin.binnumber);
                                        //利用linq获得统计的list
                                        var stalist = starp.Select(p => p.statistic).ToList();
                                        if (stalist.Count > 0)
                                        {
                                            calsave_Alllist.statisticlst.AddRange(stalist);
                                        }
                                        //添加每一个通道的rangepair
                                        foreach (var s in starp)
                                        {
                                            calsave_Alllist.rplst.AddRange(s.rplst);
                                        }

                                        var steering = await Tools_SteeringImport.GetSteeringV2Async(data, admin, row);
                                        if (row.importsteering == 1)
                                        {
                                            if (steering.Count > 0)
                                            {
                                                calsave_Alllist.steeringlst.AddRange(steering);
                                            }
                                            else 
                                            {
                                                result.Add($"{csvfile.Name}半小时转向切片数量为0，可能是转向所需通道名有误");
                                            }
                                        }
                                       
                                       
                                        var spdfromto = await Tools_SpdFromtoImport.GetSpdFromtoPrecisionAsync(data, admin, row);
                                        if (spdfromto.Count > 0)
                                        {
                                            calsave_Alllist.spdfromtolst.AddRange(spdfromto);
                                        }
                                    }
                                    else
                                    {
                                        var error = data.status == 1 ? "有空值或NaN" : data.status == 2 ? "不是数字" : "文件被占用";
                                        var info = $"{row.vehicle}文件夹{new DirectoryInfo(d).Name}的{csvfile.Name}的列名为{data.errorname}行号为{data.errorrow}半小时速度出现了错误为{error} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}{Environment.NewLine}";
                                        result.Add(info);
                                        return;
                                    }
                                }
                                //以下是添加记录表的数据
                                if (calsave_Alllist.spdlst.Count > 0)
                                {
                                    var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.spd);
                                    calsave_Alllist.recordlst.Add(record);
                                }
                                if (calsave_Alllist.rpmlst.Count > 0)
                                {
                                    var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.engrpm);
                                    calsave_Alllist.recordlst.Add(record);
                                }
                                if (calsave_Alllist.gpslst.Count > 0)
                                {
                                    var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.gps);
                                    calsave_Alllist.recordlst.Add(record);
                                }
                                if (calsave_Alllist.statisticlst.Count > 0)
                                {
                                    var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.statistics);
                                    calsave_Alllist.recordlst.Add(record);
                                }
                                if (calsave_Alllist.steeringlst.Count > 0)
                                {
                                    var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.steering);
                                    calsave_Alllist.recordlst.Add(record);
                                }
                                if (calsave_Alllist.spdfromtolst.Count > 0)
                                {
                                    var record = Tools_RecordImport.GetImportRecord(row, year, dirname, (byte)ImportType.spdfromto);
                                    calsave_Alllist.recordlst.Add(record);
                                }
                                //先创建输出文件夹
                                var newsavepath = row.savepath.YXHPathReplace();
                                Directory.CreateDirectory(newsavepath);
                                var newsavedir = Path.Combine(newsavepath, dirname);
                                //result.Add($"开始进行{dirname}文件半小时保存  {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                                //保存csv
                                await YXHCreateCSVAsync(calsave_Alllist, newsavedir);
                                //result.Add($"{dirname}文件半小时保存完毕  {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                                dtimer.Stop();
                                result.Add($"{dirname}半小时计算完成时间为{dtimer.Elapsed.TotalMinutes:0.00}分");
                            }
                        }
                        else
                        {
                            var noinfo = $"你选的年份和csv文件的年份不相等，请重新选择日期 {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}{Environment.NewLine}";
                            result.Add(noinfo);
                            return ;
                        }
                    });
                    tasks.Add(task);
                }
                await Task.WhenAll(tasks.ToArray());
                Stimer.Stop();
                result.Add($"半小时计算完成总时间为{Stimer.Elapsed.TotalMinutes:0.00}分");
            }
            else
            {
                var noinfo = $"你选的路径{row.inputpath}没有{row.vehicle}的数据 {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}{Environment.NewLine}";
                result.Add(noinfo);
            }
            return result;
        }


        /// <summary>
        /// 把所有计算后的数据保存成多个csv
        /// </summary>
        /// <param name="calsave_Alllist"></param>
        /// <param name="savepath"></param>
        /// <returns></returns>
        [Obsolete]
        public static async Task YXHCreateCSVMultiThreadAsync(calsave_alllist calsave_Alllist,string savepath)
        {
            try
            {
                Type type = calsave_Alllist.GetType();
                FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
                int numberOfFields = fields.Length;
                List<Task> tasks = new List<Task>();
                foreach (var part in fields)
                {
                    Task task = Task.Run(async () =>
                    {
                        switch (part.Name)
                        {
                            case "spdlst":
                                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.spdlst, Path.Combine(savepath, filenames[0]));
                                break;
                            case "rpmlst":
                                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.rpmlst, Path.Combine(savepath, filenames[1]));
                                break;
                            case "gpslst":
                                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.gpslst, Path.Combine(savepath, filenames[2]));
                                break;
                            case "statisticlst":
                                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.statisticlst, Path.Combine(savepath, filenames[3]));
                                break;
                            case "steeringlst":
                                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.steeringlst, Path.Combine(savepath, filenames[4]));
                                break;
                            case "spdfromtolst":
                                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.spdfromtolst, Path.Combine(savepath, filenames[5]));
                                break;
                            case "recordlst":
                                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.recordlst, Path.Combine(savepath, filenames[6]));
                                break;
                        }
                    });
                    tasks.Add(task);
                }
                await Task.WhenAll(tasks.ToArray());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
         
        }

        public static async Task YXHCreateCSVAsync(calsave_alllist calsave_Alllist, string savepath)
        {
            try
            {
                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.spdlst, Path.Combine(savepath, filenames[0]));
                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.rpmlst, Path.Combine(savepath, filenames[1]));
                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.gpslst, Path.Combine(savepath, filenames[2]));
                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.statisticlst, Path.Combine(savepath, filenames[3]));
                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.steeringlst, Path.Combine(savepath, filenames[4]));
                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.spdfromtolst, Path.Combine(savepath, filenames[5]));
                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.rplst, Path.Combine(savepath, filenames[6]));
                await CSVHelperClass.SaveCSVfromListTData(calsave_Alllist.recordlst, Path.Combine(savepath, filenames[7]));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }

        }
    }
}
